package com.boluo.audit.service.impl;

import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.boluo.common.utils.DateUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.boluo.audit.mapper.AudBpmnInfoMapper;
import com.boluo.audit.domain.AudBpmnInfo;
import com.boluo.audit.service.IAudBpmnInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;

/**
 * 流程定义明细Service业务层处理
 * 
 * @author boluo
 * @date 2023-04-16
 */
@Service
public class AudBpmnInfoServiceImpl implements IAudBpmnInfoService 
{
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private AudBpmnInfoMapper audBpmnInfoMapper;

    /**
     * 查询流程定义明细
     * 
     * @param id 流程定义明细主键
     * @return 流程定义明细
     */
    @Override
    public AudBpmnInfo selectAudBpmnInfoById(Long id)
    {
        return audBpmnInfoMapper.selectAudBpmnInfoById(id);
    }

    /**
     * 查询流程定义明细列表
     * 
     * @param audBpmnInfo 流程定义明细
     * @return 流程定义明细
     */
    @Override
    public List<AudBpmnInfo> selectAudBpmnInfoList(AudBpmnInfo audBpmnInfo)
    {
        return audBpmnInfoMapper.selectAudBpmnInfoList(audBpmnInfo);
    }

    /**
     * 新增流程定义明细
     * 
     * @param audBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int insertAudBpmnInfo(AudBpmnInfo audBpmnInfo)
    {
        return audBpmnInfoMapper.insertAudBpmnInfo(audBpmnInfo);
    }

    /**
     * 修改流程定义明细
     * 
     * @param audBpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int updateAudBpmnInfo(AudBpmnInfo audBpmnInfo)
    {
        return audBpmnInfoMapper.updateAudBpmnInfo(audBpmnInfo);
    }

    /**
     * 批量删除流程定义明细
     * 
     * @param ids 需要删除的流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteAudBpmnInfoByIds(Long[] ids)
    {
        return audBpmnInfoMapper.deleteAudBpmnInfoByIds(ids);
    }

    /**
     * 删除流程定义明细信息
     * 
     * @param id 流程定义明细主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteAudBpmnInfoById(Long id)
    {
        // 参数校验(id不能为null)

        AudBpmnInfo audBpmnInfo = audBpmnInfoMapper.selectAudBpmnInfoById(id);
        Assert.notNull(audBpmnInfo,"流程id错误");

        // 根据Key 和版本号查询流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(audBpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(audBpmnInfo.getVersion().intValue())
                .singleResult();

        // 删除 Activiti 数据
        repositoryService.deleteDeployment(processDefinition.getDeploymentId(),true);

        return audBpmnInfoMapper.deleteAudBpmnInfoById(id);
    }

    @Override
    @Transactional
    public int saveBpmnInfo(AudBpmnInfo audBpmnInfo, InputStream inputStream) {
        // 参数校验

        // 校验上传的是不是流程图
        String bpmnLabel = audBpmnInfo.getBpmnLabel();
        Assert.state(bpmnLabel.endsWith("bpmn"),"非法文件");

        // 调用 Activiti API 部署流程定义
        Deployment deployment = repositoryService.createDeployment()
                .addInputStream(bpmnLabel, inputStream)
                .deploy();

        // 根据部署id 查询流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployment.getId())
                .singleResult();

        // 再往我们设计表存数据
        audBpmnInfo.setDeployTime(DateUtils.getNowDate());
        audBpmnInfo.setProcessDefinitionKey(processDefinition.getKey());
        audBpmnInfo.setVersion((long)processDefinition.getVersion());


        return audBpmnInfoMapper.insertAudBpmnInfo(audBpmnInfo);
    }

    @Override
    public InputStream getInputStream(Long id, String type) {
        // 参数校验
        AudBpmnInfo audBpmnInfo = audBpmnInfoMapper.selectAudBpmnInfoById(id);

        // 根据Key 和版本号查询流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(audBpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(audBpmnInfo.getVersion().intValue())
                .singleResult();

        if ("xml".equals(type)) {
           // 查看xml




            return repositoryService.getProcessModel(processDefinition.getId());

        } else {
            // 查看流程图
            // 这个对象用来画图的,内存中
            DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();

            // BpmnModel 对象 用来封装我们画的流程
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());

            // 画图,返回InputStream对象
            return generator.generateDiagram(
                    // 封装流程图
                    bpmnModel,
                    // 哪个任务节点高亮
                    Collections.emptyList(),
                    Collections.emptyList(),
                    // 字体
                    "宋体",
                    "宋体",
                    "宋体");

        }

       //        return repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), audBpmnInfo.getBpmnLabel());

    }
}
